
package com.cortex.pineapple.view;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ClipboardManager.OnPrimaryClipChangedListener;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings.PluginState;
import android.webkit.WebView;
import android.webkit.WebView.HitTestResult;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.Toast;
import android.widget.ViewFlipper;

import com.cortex.pineapple.R;
import com.cortex.pineapple.utilities.MessagesLog;
import com.cortex.pineapple.view.RowSearch.OnRunSearchListener;


public class BrowserView extends ScrollView  implements OnClickListener{

	private WebView webView;
	private boolean isLoading;
	private OnIconClickListener onIconClickListener;
	private RowSearch rowSearch;
	private ImageView icon,forward,back,refresh;
	private ViewFlipper flipperIcon;
	private RelativeLayout navBar;
	private OnBrowserChangedListener onStateChangedListener;
	private OnSectionSelectedListener onSectionSelectedListener;
	private STATE_BROWSER state = STATE_BROWSER.PAGE_FINIHED;
	private ClipboardManager clipboard;
	private List<String> sectionsToMark = new ArrayList<String>();
	private ImageView showSeletedText;

	public BrowserView(Context context) {
		super(context);
		init();
	}
	public BrowserView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	public BrowserView(Context context, AttributeSet attrs,int style) {
		super(context, attrs,style);
		init();
	}
	private void init(){
		LayoutInflater.from(getContext()).inflate(R.layout.view_browser, this);
		rowSearch = (RowSearch)findViewById(R.id.rowSearch);
		forward = (ImageView)findViewById(R.id.forward);
		back = (ImageView)findViewById(R.id.back);
		refresh = (ImageView)findViewById(R.id.imgRefresh);
		flipperIcon = (ViewFlipper)findViewById(R.id.flipperIcon);
		icon = (ImageView)findViewById(R.id.icon);
		navBar = (RelativeLayout)findViewById(R.id.navBar);
		showSeletedText = (ImageView)findViewById(R.id.showSeletedText);
		initWebView();
		initListeners();

		Animation in = AnimationUtils.loadAnimation(getContext(), R.anim.push_left_and_fade_in);
		Animation out = AnimationUtils.loadAnimation(getContext(), R.anim.push_left_and_fade_out);
		flipperIcon.setInAnimation(in);
		flipperIcon.setOutAnimation(out);
		//		loadUrl("http://www.ynet.co.il/articles/0,7340,L-4503104,00.html");
	}
	private void initWebView(){
		webView = (WebView)findViewById(R.id.webView);
		webView.getSettings().setLoadsImagesAutomatically(true);
		webView.getSettings().setJavaScriptEnabled(true);
		webView.getSettings().setUseWideViewPort(true);
		webView.getSettings().setLoadWithOverviewMode(true);
		webView.getSettings().setPluginState(PluginState.ON);
		webView.getSettings().setDomStorageEnabled(true);
		webView.setWebViewClient(new ClientWebView());
		webView.setFocusableInTouchMode(true);
		// to allow html5 videos in webView 
		webView.setWebChromeClient(new WebChromeClient());

		clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
		clipboard.addPrimaryClipChangedListener(new OnPrimaryClipChangedListener() {

			@Override
			public void onPrimaryClipChanged() {
				String lastSelectedText = "";
				if (clipboard != null) {
					String text = null;
					if(clipboard.hasPrimaryClip()){
						ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
						text = item.getText().toString();
						if(!lastSelectedText.equals(text)){
							if(onSectionSelectedListener != null){
								onSectionSelectedListener.sectionSelected(text);
							}
							lastSelectedText = text;
							showSeletedText.setY(getScrollY() + (getHeight()/2));
							Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.fade_in);
							animation.setDuration(3000);
							animation.setAnimationListener(new AnimationListener() {
								
								@Override
								public void onAnimationStart(Animation animation) {
									showSeletedText.setVisibility(VISIBLE);
								}
								
								@Override
								public void onAnimationRepeat(Animation animation) {
									// TODO Auto-generated method stub
									
								}
								
								@Override
								public void onAnimationEnd(Animation animation) {
									showSeletedText.setVisibility(GONE);
								}
							});
							showSeletedText.startAnimation(animation);

						}
					}
				}
			}
		});
	}

	public void setOnIconClickListener(OnIconClickListener onIconClickListener) {
		this.onIconClickListener = onIconClickListener;
	}
	public void setOnBrowserChangedListener(OnBrowserChangedListener onStateChangedListener) {
		this.onStateChangedListener = onStateChangedListener;
	}
	public void setOnSectionSelectedListener(OnSectionSelectedListener onSectionSelectedListener) {
		this.onSectionSelectedListener = onSectionSelectedListener;
	}
	private String getScript(){
		String s = 
				"window.document.onclick = myClickHandler;" +  
						"function myClickHandler() {" + 	
						"var bodyElement = document.getElementsByTagName(\"body\")[0];" +     
						"highlightText(bodyElement);" + 	
						"}" + 
						"function highlightText(node){" +
						"var sectionsToMark=" + convertToArrayJsp(sectionsToMark) + ";" +
						"for (var i = 0; i < sectionsToMark.length; i++) {" + 
						"var text = sectionsToMark[i];" + 

        	"var innerHTML = node.innerHTML;" + 
        	"if(innerHTML != undefined){" +         
        	"var index = innerHTML.indexOf(text);" +         
        	"if ( index >= 0 ){" +              
        	"innerHTML = innerHTML.substring(0,index) + \"<span style=background-color:yellow;>\" + innerHTML.substring(index,index+text.length) + \"</span>\" + innerHTML.substring(index + text.length);" + 
        	"node.innerHTML = innerHTML;" +         
        	"}" +     
        	"}" + 
        	"}" +
        	"}";
		return "javascript:(function() { " + s + "})()";
	}
	private String convertToArrayJsp(List<String> list){
		StringBuilder ret = new StringBuilder();
		ret.append("[");
		for (int i = 0; i < list.size(); i++) {
			ret.append("\"" + list.get(i) + "\"");
			if(i<list.size()-1){
				ret.append(",");
			}
		}
		ret.append("]");
		return ret.toString();
	}
	private class ClientWebView extends WebViewClient{
		boolean loadingFinished = true;
		boolean redirect = false;
		@Override
		public void onPageStarted(WebView view, String url, Bitmap favicon) {
			setNavState(true);
			rowSearch.setValue(url);
			state = STATE_BROWSER.PAGE_STARTED;
			if(onStateChangedListener != null){
				onStateChangedListener.stateChanged(state, url,view.getFavicon());
			}
			scrollTo(0, 0);
			loadingFinished = false;
		}
		public void onPageFinished(WebView view, String url) {
			setNavState(false);

			if(!redirect){
				loadingFinished = true;
			}

			if(loadingFinished && !redirect){
				if(onStateChangedListener != null){
					state = STATE_BROWSER.PAGE_FINIHED;
					onStateChangedListener.stateChanged(state, url,view.getFavicon());
				}

				String s = getScript();
				webView.loadUrl(s);

			} else{
				redirect = false; 
			}
		}
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			if (!loadingFinished) {
				redirect = true;
			}

			loadingFinished = false;
			view.loadUrl(url);
			state = STATE_BROWSER.PAGE_LOADING;
			return true;
		}

		@Override
		public void onReceivedError(WebView view, int errorCode,
				String description, String failingUrl) {
			super.onReceivedError(view, errorCode, description, failingUrl);
			if(onStateChangedListener != null){
				state = STATE_BROWSER.PAGE_ERROR;
				onStateChangedListener.stateChanged(state, failingUrl,null);
			}
		}
	}

	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		// show web view below nav bar when the page in top
		if(t == 0){
			RelativeLayout.LayoutParams params = (android.widget.RelativeLayout.LayoutParams) webView.getLayoutParams();
			params.addRule(RelativeLayout.BELOW, navBar.getId());
			webView.setLayoutParams(params);
			navBar.setY(0);
			return;
		}
		// check if scrollView arrived to end
		View view = (View) getChildAt(getChildCount()-1);   
		int diff = (view.getBottom()-(getHeight()+getScrollY()));
		if( diff <= 0 ){
			navBar.setY(t - navBar.getHeight());
			return;
		}
		// show nav bar on web view when user scroll up 
		if(t<oldt){
			navBar.setY(t);
		}

	}

	private void initListeners(){
		icon.setOnClickListener(this);
		back.setOnClickListener(this);
		forward.setOnClickListener(this);
		refresh.setOnClickListener(this);
		rowSearch.setOnRunSearchListener(new OnRunSearchListener() {

			@Override
			public void search(String query) {
				loadUrl(query);
			}
		});

	}

	public boolean isCanGoBack(){
		return webView.canGoBack();
	}
	public boolean isCanGoForward(){
		return webView.canGoForward();
	}
	private void setNavState(boolean isStarted){
		isLoading = isStarted;
		setNavButtons();
		View currentView = flipperIcon.getChildAt(flipperIcon.getDisplayedChild());
		if(currentView.getId() == icon.getId() && isLoading){
			flipperIcon.setDisplayedChild(1); // show progress bar
		}
		else if(!isLoading){
			flipperIcon.setDisplayedChild(0); // show logo
		}
	}
	private void setNavButtons(){
		int image;
		boolean clickable;

		clickable = isCanGoBack();
		image = clickable?R.drawable.back_on:R.drawable.back_off;
		back.setImageResource(image);
		back.setClickable(clickable);

		clickable = isCanGoForward();
		image = clickable?R.drawable.forward_on:R.drawable.forward_off;
		forward.setImageResource(image);
		forward.setClickable(clickable);

	}
	private void goBack(){
		webView.goBack(); 
	}
	private void goForward(){
		webView.goForward(); 
	}
	public boolean isLoading() {
		return state != STATE_BROWSER.PAGE_FINIHED && state != STATE_BROWSER.PAGE_ERROR;
	}
	public boolean isPageLoaded(){
		return !rowSearch.getValue().isEmpty();
	}
	private void reload(){
		webView.reload();
	}
	public void loadUrl(String url){
		sectionsToMark.clear();
		if(!url.contains(getResources().getString(R.string.http))){
			url = getResources().getString(R.string.http) + url;
		}
		webView.loadUrl(url);

	}
	public void loadUrl(String url,List<String> sectionsTomMark){
		loadUrl(url);
		this.sectionsToMark = sectionsTomMark;
	}
	public void stopLoding(){
		webView.stopLoading();
	}
	public void saveState(Bundle outState){
		webView.saveState(outState);
	}
	public void restoreState(Bundle savedInstanceState){
		webView.restoreState(savedInstanceState);
	}
	@Override
	public void onClick(View v) {
		if(v.getId() == icon.getId()){
			if(onIconClickListener != null){
				onIconClickListener.onIconClick();
			}
		}
		else if(v.getId() == forward.getId()){
			goForward();
		}
		else if(v.getId() == back.getId()){
			goBack();
		}
		else if(v.getId() == refresh.getId()){
			reload();
		}
	}

	public interface OnIconClickListener{
		void onIconClick();
	}

	public interface OnBrowserChangedListener{
		void stateChanged(STATE_BROWSER state,String url,Bitmap favicon);
	}
	public interface OnSectionSelectedListener{
		void sectionSelected(String section);
	}
	public enum STATE_BROWSER{
		PAGE_STARTED,
		PAGE_FINIHED,
		PAGE_LOADING,
		PAGE_ERROR
	}

}
